package com.cskaoyan.javase.basic._2variable._3notice;

/**
 * 浮点数的精度问题
 * 浮点数是有精度问题的,主要表现为:
 *      1.浮点数的有效位数是有限的
 *      2.二进制小数可能出现循环的情况
 * 在十进制下,10除以3,是除不尽的,是一个无限的循环小数
 * 在二进制下,也是一样的,二进制小数也可能出现无限循环
 *
 * 比如用二进制小数表示十进制的0.1
 * 这里涉及一个二进制表示小数的转换问题，规则如下：
 * 十进制正小数（0.开头）转换成二进制，先用小数部分乘以2，取结果的整数部分(必然是1或者0)，
 * 然后小数部分继续乘2
 * 直到小数部分为0，或者已经达到了最大的位数
 * 最终的结果（0.开头）正序排列
 *
 * 0.1 * 2 = 0.2 --> 0
 * 0.2 * 2 = 0.4 --> 0
 * 0.4 * 2 = 0.8 --> 0
 * 0.8 * 2 = 1.6 --> 1
 * 0.6 * 2 = 1.2 --> 1
 * 0.2 * 2 = 0.4 --> 0
 * 0.4 * 2 = 0.8 --> 0
 * ....
 * 是一个无限的循环小数
 * 本身浮点数的有效位数就有限,现在又来了无限循环小数,浮点数的精确度进一步下降了
 *
 * 所以浮点数实在不是一个精确的数值,它只是一个近似的表示
 * 如果是简简单单做一下运算,不在乎精度,那么用浮点数是可以的
 * 但是如果对精度很敏感,比如财务运算,是一定不能使用浮点数的
 *
 * 面试题:
 *      你们公司的财务系统,算钱时,有小数怎么算啊?
 *      是不能用浮点数的(用什么呢?)
 *
 * @since 16:12
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo3 {
    public static void main(String[] args) {
        // float的有效位数只有7-8位,超出的位数就会被舍弃
        float a = 0.1F;
        float b = 0.10000000000001F;
        System.out.println(a == b);


        float c = 1 - 0.9F;
        double d = 1 - 0.9;
        System.out.println(c);
        System.out.println(d);


        // float的0.1和double的0.1是一个数吗?
        /*
            浮点数是一种数字表示方式
            float和double是完全不同的
            即便是一个数,它们表示出来也有可能完全不同
         */
        System.out.println(0.1 == 0.1F);
    }
}
